package orange.com.openstack.swift;

import java.io.File;
import java.io.InputStream;

import orange.com.openstack.sahara.Client;

import org.javaswift.joss.client.factory.AccountConfig;
import org.javaswift.joss.client.factory.AccountFactory;
import org.javaswift.joss.model.Account;
import org.javaswift.joss.model.Container;
import org.javaswift.joss.model.StoredObject;

/**
 * @author osvaldo.cocucci@gmail.com
 * 
 */
public class Uploader {
	AccountConfig config;
	Account account;
	String username, password, tenantName;
	String authUrl;

	/**
	 * @param username
	 * @param password
	 * @param tenantName
	 * @param authUrl
	 * 
	 *            constructor
	 */
	public Uploader(String username, String password, String tenantName,
			String authUrl) {

		this.username = username;
		this.password = password;
		this.tenantName = tenantName;
		this.authUrl = authUrl;
	}

	/**
	 * create a swift account connection
	 * 
	 * @return an account according to the credential of the created object
	 */
	public Account connect() {
		config = new AccountConfig();
		config.setUsername(username);
		config.setPassword(password);
		config.setAuthUrl(authUrl);
		config.setTenantName(tenantName);
		return new AccountFactory(config).createAccount();
	}

	/**
	 * @param containerName
	 * 
	 *            creates a container
	 * @return true if container has been created, false if it already exists
	 */
	public Container createContainer(String containerName) {
		if (account == null)
			account = connect();

		Container myContainer = account.getContainer(containerName);
		if (!myContainer.isPublic() && !myContainer.exists()) {
			myContainer.create();
			Client.logger.info("container " + containerName + " created");

		} else {
			Client.logger.info("container " + containerName + " already exist");

		}
		return myContainer;
	}

	/**
	 * @param localPath
	 * @param containerName
	 *            upload the localfile to the given container, if the file
	 *            doesn't exist
	 * @return the storedObject reference of this new uploaded file
	 */
	public StoredObject upload(String localPath, String containerName) {
		if (account == null)
			account = connect();

		Container myContainer = account.getContainer(containerName);
		if (!myContainer.exists()) {
			myContainer.create();
			Client.logger.info("container " + containerName + " created");
		}

		File file2Upload = new File(localPath);
		StoredObject someFile = myContainer.getObject(file2Upload.getName());
		if (!someFile.exists()) {
			Client.logger.info("sending file ... ");
			someFile.uploadObject(file2Upload);
			Client.logger.info(file2Upload.getName() + " has been sent ...");
		} else {
			Client.logger.info(file2Upload.getName() + " already exist ...");
		}

		return someFile;
	}

	/**
	 * @param stream 
	 * @param fileName the name of the file
	 * @param containerName
	 *            upload the stream to the given container, if the file
	 *            doesn't exist
	 * @return the storedObject reference of this new uploaded file
	 */
	public StoredObject upload(InputStream stream, String fileName,
			String containerName) {
		if (account == null)
			account = connect();

		Container myContainer = account.getContainer(containerName);
		if (!myContainer.exists()) {
			myContainer.create();
			Client.logger.info("container " + containerName + " created");
		}

		StoredObject someFile = myContainer.getObject(fileName);
		if (!someFile.exists()) {
			Client.logger.info("sending file ... ");
			someFile.uploadObject(stream);
			Client.logger.info(fileName + " has been sent ...");
		} else {
			Client.logger.info(fileName + " already exist ...");
		}

		return someFile;
	}

	/**
	 * 
	 * @param containerName
	 *            list all the storedObject inclued in this container
	 */
	public void listStoredObject(String containerName) {
		if (account == null)
			account = connect();

		for (Container container : account.list()) {
			Client.logger.info(container.getName());
			for (StoredObject object : container.list())
				Client.logger.info(object.getName());
		}
	}

	/**
	 * list all the containers
	 */
	public void listContainers() {
		if (account == null)
			account = connect();

		for (Container container : account.list()) {
			System.out.println(container.getName());
		}

	}

}
